package com.zk.yygh.dict.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.SelectOne;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zk.yygh.dict.listener.DictListener;
import com.zk.yygh.dict.mapper.DictMapper;
import com.zk.yygh.dict.service.DictService;
import com.zk.yygh.model.cmn.Dict;
import com.zk.yygh.vo.cmn.DictEeVo;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: 张凯
 * @date: 2022/5/21 - 21:56
 */
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {
    //根据传入的id来查询其子一级数据
    //当前缓存策略：第一次(或没有缓存)查询进入数据库=>放入缓存=>第二次查询进入缓存查询
    @Cacheable(value = "dict",keyGenerator="keyGenerator")
    @Override
    public List<Dict> getChildById(Long id) {
        //条件构造器
        QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
        dictQueryWrapper.eq("parent_id",id);
        //查询所有的子节点
        List<Dict> dicts = this.baseMapper.selectList(dictQueryWrapper);
        //给所有子节点赋值是否含有子节点
        for (int i = 0; i < dicts.size(); i++) {
            boolean flag = isHasChild(dicts.get(i).getId());
            dicts.get(i).setHasChildren(flag);
        }
        return dicts;
    }

    //导出数据字典
    @Override
    public void exportDict(HttpServletResponse response) {
        //1.设置response的头信息
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = null;
        try {
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            fileName = URLEncoder.encode("数据字典", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        //2.查询数据库获取数据集合
        List<Dict> dictList = baseMapper.selectList(null);
        //3.将查询的数据字典转为excel操作的对象
        List<DictEeVo> dictEeVoList=new ArrayList<>();
        for(Dict dict:dictList){
            DictEeVo dictEeVo = new DictEeVo(dict.getId(), dict.getParentId(), dict.getName(), dict.getValue(), dict.getDictCode());
            dictEeVoList.add(dictEeVo);
        }
        //4.将数据写出
        try {
            //可通过流，也可通过路径
            EasyExcel.write(response.getOutputStream(),DictEeVo.class)
                    .sheet("数据字典")
                    .doWrite(dictEeVoList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //数据字典导入
    //导入数据后清空所有的缓存
    @CacheEvict(value = "dict",allEntries = true)
    @Override
    public void importDict(MultipartFile file){

        //EasyExcel读操作
        try {
            EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper))
                    .sheet("新增数据字典")
                    .doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取相关信息名字
    @Cacheable(value = "dict",keyGenerator="keyGenerator")
    @Override
    public String getName(String dictCode, Integer value) {
        if (StringUtils.isEmpty(dictCode)){
            //只根据value来查询
            Dict dict = this.baseMapper.selectOne(new QueryWrapper<Dict>().eq("value", value));
            if (dict!=null){
                return dict.getName();
            }
        }else {
            //根据编码和值来查询
            Dict dict = this.baseMapper.selectOne(new QueryWrapper<Dict>().eq("dict_code", dictCode));
            if (dict!=null){
                //不为空则获取其id,查询其该编码下子节点的value
                Dict dict1 = this.baseMapper.selectOne(new QueryWrapper<Dict>().eq("parent_id", dict.getId()).eq("value", value));
                if (dict1!=null){
                    return dict1.getName();
                }
            }
        }
        return null;
    }

    @Override
    public List<Dict> getProCityName(String province) {
        Dict dict = this.baseMapper.selectOne(new QueryWrapper<Dict>().eq("dict_code", province));
        List<Dict> dictList=null;
        if (dict!=null){
            dictList = getChildById(dict.getId());
        }
        return dictList;
    }

    @Override
    public List<Dict> getCityByProvince(String province) {
        List<Dict> dictList = this.baseMapper.selectList(new QueryWrapper<Dict>().eq("parent_id", Integer.parseInt(province)));
        return dictList;
    }


    //返回当前节点是否有子节点
    public boolean isHasChild(Long id){
        QueryWrapper<Dict> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id",id);
        int num = this.baseMapper.selectCount(wrapper);
        return num>0;
    }
}
